﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XSTDZ.ERP.Application.DataContracts;
using AutoMapper;
using XSTDZ.ERP.Domain.Models;
using XSTDZ.ERP.Core.Repositories;
using XSTDZ.ERP.Core.Generator;

namespace XSTDZ.ERP.Application.Implements
{
    public class ProductServiceImpl : ApplicationServiceBase, IProductService
    {
        IRepository<ProductType> _productTypeRepository;
        IRepository<ProductInfo> _productRepository;
        IRepository<Storehouse> _storehouseRepository;
        IRepository<ProductProcedure> _ppProcedure;
        public ProductServiceImpl(IRepositoryContext repositoryContext, IRepository<ProductType> productTypeRepository, IRepository<ProductInfo> productRepository, IRepository<Storehouse> storehouseRepository, IRepository<ProductProcedure> ppProcedure)
            : base(repositoryContext)
        {
            this._productTypeRepository = productTypeRepository;
            this._productRepository = productRepository;
            this._storehouseRepository = storehouseRepository;
            this._ppProcedure = ppProcedure;
        }


        #region 商品类别
       
        public void AddProductType(ProductTypeDto productTypeDto)
        {
            var productType = Mapper.Map<ProductTypeDto, ProductType>(productTypeDto);
            productType.Id = (Guid)new SequentialIdentityGenerator().Next;
            if (productType.Id != productType.ParentID && !productType.ParentID.Equals(Guid.Empty))
            {
                productType.Parent = this._productTypeRepository.GetByKey(productType.ParentID);
            }
            productType.Init();
            this._productTypeRepository.Add(productType);
            this.Context.Commit();
        }

        public void UpdateProductType(ProductTypeDto productTypeDto)
        {
            var productType = Mapper.Map<ProductTypeDto, ProductType>(productTypeDto);
           
            this._productTypeRepository.Update(productType);
            this.Context.Commit();
        }

        public void ConvertProductTypeDeleteState(Guid productTypeId)
        {
            var productType = this._productTypeRepository.GetByKey(productTypeId);
            productType.SetDeleteState();
            this._productTypeRepository.Update(productType);
            this.Context.Commit();
        }
       
        public ProductTypeDto GetProductType(Guid productTypeId)
        {
            var productType = this._productTypeRepository.GetByKey(productTypeId);
            return Mapper.Map<ProductType, ProductTypeDto>(productType);
        }

        public IList<ProductTypeDto> GetAllProductType()
        {
            var productType = this._productTypeRepository.GetAll();
            return Mapper.Map <IList<ProductType>, IList<ProductTypeDto>>(productType.ToList());
        }
        public IList<ProductTypeDto> GetAllProductTypeNormail()
        {
            var productType = this._productTypeRepository.GetAll(d=>d.Deleted==0);
            return Mapper.Map<IList<ProductType>, IList<ProductTypeDto>>(productType.ToList());
        }
        public IList<ProductTypeDto> GetAllProductTypeDelete()
        {
            var productType = this._productTypeRepository.GetAll(d => d.Deleted == 1);
            return Mapper.Map<IList<ProductType>, IList<ProductTypeDto>>(productType.ToList());
        }
        public IList<ProductTypeDto> GetAllProductType(Guid parentId)
        {
            var productType = this._productTypeRepository.GetAll(p => p.ParentID == parentId && p.ParentID !=p.Id);
            return Mapper.Map<IList<ProductType>, IList<ProductTypeDto>>(productType.ToList());
        }
        public IList<ProductTypeDto> GetAllProductType(int level)
        {
            var productType = this._productTypeRepository.GetAll(p => p.Level == level);
            return Mapper.Map<IList<ProductType>, IList<ProductTypeDto>>(productType.ToList());
        }
        public IList<ProductTypeDto> GetAllProductType(string typeName)
        {
            var productType = this._productTypeRepository.GetAll(p => p.TypeName.Contains(typeName));
            return Mapper.Map<IList<ProductType>, IList<ProductTypeDto>>(productType.ToList());
        }
        #endregion
        #region 商品
        
        
        public void AddProduct(ProductInfoDto productInfoDto)
        {
            var productInfo = Mapper.Map<ProductInfoDto, ProductInfo>(productInfoDto);
            productInfo.Id = (Guid)new SequentialIdentityGenerator().Next;
            productInfo.Init();
            this._productRepository.Add(productInfo);
            this.Context.Commit();
        }

        public void UpdateProduct(ProductInfoDto productInfoDto)
        {
            var productInfo = Mapper.Map<ProductInfoDto, ProductInfo>(productInfoDto);
            productInfo.Init();
            this._productRepository.Update(productInfo);
            this.Context.Commit();
        }

        public void ConvertProductDeleteState(Guid productId)
        {
            var productInfo = this._productRepository.GetByKey(productId);
            productInfo.SetDeleteState();
            this._productRepository.Update(productInfo);
            this.Context.Commit();
        }

        public ProductInfoDto GetProductInfoDto(Guid productId)
        {
            var productInfo = this._productRepository.GetByKey(productId);
            return Mapper.Map<ProductInfo, ProductInfoDto>(productInfo);
        }

        public IList<ProductInfoDto> GetProductInfoDto(int pageIndex, int pageSize)
        {
            var productInfos = this._productRepository.GetAll(pageIndex, pageSize);
            return Mapper.Map<IList<ProductInfo>, IList<ProductInfoDto>>(productInfos.ToList());
        }
        public IList<ProductInfoDto> GetProductInfoDto(int pageIndex, int pageSize, bool isDelete)
        {
            var productInfos = this._productRepository.GetAll(p => isDelete?p.Deleted==1:p.Deleted==0, pageIndex, pageSize);
            return Mapper.Map<IList<ProductInfo>, IList<ProductInfoDto>>(productInfos.ToList());
        }
        public IList<ProductInfoDto> GetProductInfoDto(int pageIndex, int pageSize, Guid productTypeId)
        {
            var productInfos = this._productRepository.GetAll(pageIndex, pageSize, p => p.ProductTypeID == productTypeId);
            return Mapper.Map<IList<ProductInfo>, IList<ProductInfoDto>>(productInfos.ToList());
        }
        #endregion
        #region 仓库服务
        public void AddStorehouse(StorehouseDto storehouseDto)
        {
            var wareHouse = Mapper.Map<StorehouseDto, Storehouse>(storehouseDto);
            wareHouse.Id = (Guid)new SequentialIdentityGenerator().Next;
            wareHouse.Init();
            this._storehouseRepository.Add(wareHouse);
            this.Context.Commit();
        }

        public void UpdateStorehouse(StorehouseDto storehouseDto)
        {
            var wareHouse = Mapper.Map<StorehouseDto, Storehouse>(storehouseDto);
            this._storehouseRepository.Update(wareHouse);
            this.Context.Commit();
        }

        public void ConvertStorehouseDeleteState(Guid storehouseId)
        {
            var wareHouse = this._storehouseRepository.GetByKey(storehouseId);
            wareHouse.SetDeleteState();
            this._storehouseRepository.Update(wareHouse);
            this.Context.Commit();
        }

        public StorehouseDto GetStorehouse(Guid storehouseId)
        {
            var wareHouse = this._storehouseRepository.GetByKey(storehouseId);
            return Mapper.Map<Storehouse, StorehouseDto>(wareHouse);
        }
      
        public IList<StorehouseDto> GetAllStorehouse()
        {
            var wareHouses = this._storehouseRepository.GetAll();
            return Mapper.Map<IList<Storehouse>, IList<StorehouseDto>>(wareHouses.ToList());
        }

        public IList<StorehouseDto> GetAllStorehouse(Guid orgId)
        {
            var wareHouses = this._storehouseRepository.GetAll(w => w.OrgID == orgId);
            return Mapper.Map<IList<Storehouse>, IList<StorehouseDto>>(wareHouses.ToList());
        }

        public IList<StorehouseDto> GetAllStorehouse(string orgCode)
        {
            var wareHouses = this._storehouseRepository.GetAll();// this._storehouseRepository.GetAll(w => w.Org.Code == orgCode);
            if (wareHouses != null && wareHouses.Count() != 0)
            {
                var ws = wareHouses.Where(w => w.Org.Code.Trim().ToUpper() == orgCode.Trim().ToUpper());
                return Mapper.Map<IList<Storehouse>, IList<StorehouseDto>>(ws.ToList());
            }
            return null;
        }
        #endregion
        #region 产品工序
        public Guid AddProductProcedure(ProductProcedureDto productProcedureDto)
        {
            var pp = Mapper.Map<ProductProcedureDto, ProductProcedure>(productProcedureDto);
            this._ppProcedure.Add(pp.Init());
            this.Context.Commit();
            return pp.Id;
        }
        public void UpdateProductProcedure(ProductProcedureDto productProcedureDto)
        {
            var pp = Mapper.Map<ProductProcedureDto, ProductProcedure>(productProcedureDto);
            this._ppProcedure.Update(pp);
            this.Context.Commit();
        }
        public ProductProcedureDto GetProductProcedure(Guid id)
        {
            var pp = this._ppProcedure.GetByKey(id);
            return Mapper.Map<ProductProcedure, ProductProcedureDto>(pp);
        }
        public void DeleteProductProcedure(Guid id)
        {
            var pp = this._ppProcedure.GetByKey(id);
            this._ppProcedure.Update(pp.SetDeleteState());
            this.Context.Commit();
        }
        public IEnumerable<ProductProcedureDto> GetAllProductProcedure(Guid productId)
        {
            var pplst = this._ppProcedure.GetAll(t => t.ProductID == productId);
            return Mapper.Map<IEnumerable<ProductProcedure>, IEnumerable<ProductProcedureDto>>(pplst);
        }
        #endregion
       
    }
}
